package cn.tnar.parkservice.service.impl;


import cn.tnar.parkservice.config.Constant;
import cn.tnar.parkservice.mapper.TParkMemberGroupMapper;
import cn.tnar.parkservice.model.entity.*;
import cn.tnar.parkservice.service.*;
import cn.tnar.parkservice.util.DateUtils;
import cn.tnar.parkservice.util.common.ResultCode;
import cn.tnar.parkservice.util.common.ResultJson;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author dzx
 * @ClassName:
 * @Description:
 * @date 2019年07月08日 14:51:32
 */
@Service("tParkMemberGroupServiceImpl")
@Slf4j
public class TParkMemberGroupServiceImpl extends ServiceImpl<TParkMemberGroupMapper, TParkMemberGroup> implements ITParkMemberGroupService {

    @Autowired
    private TParkMemberGroupMapper tParkMemberGroupMapper;

    @Autowired
    private ITParkInfoService itParkInfoService;

    @Autowired
    private ITCarFeesroleinfoService itCarFeesroleinfoService;

    @Autowired
    private MqService mqService;

    @Autowired
    private ITParkMemberGroupRelationService relationService;

    @Autowired
    private ITParkGroupMemberinfoService memberinfoService;

    ResultJson RESULT_JSON = new ResultJson();


    @Override
    public ResultJson insertMemberGroup(MemberGroupReq memberGroupreq) {
        Integer type = memberGroupreq.getType();
        String name = memberGroupreq.getName();
        String parkCodes = memberGroupreq.getParkCodes();
        Long parentId = memberGroupreq.getParentId();
        Integer classify = memberGroupreq.getClassify();
        if (GroupType.ZERO.type.compareTo(type) == 0) { //新增目录时界面不能绑定停车场，因此parkcode直接传当前停车场的code
            //判断parkCodes是否为空
//                if (StringUtils.isNotBlank(parkCodes)) {
//                    return getFailResultJson("会员分组目录不能绑定停车场");
//                }
            String[] parkCodeArray = parkCodes.split(",|，");
            if (parkCodeArray.length > 1) {
                return getFailResultJson("新增目录只能绑定当前停车场");
            }
            //判断同级目录下当前节点名称是否已经存在
            String parkCode = parkCodeArray[0];
            TParkMemberGroup existInParentNode = this.isExistInParentNode(name, parkCode, parentId);
            if (existInParentNode == null) {
                TParkMemberGroup tParkMemberGroup = new TParkMemberGroup();
                tParkMemberGroup.setNo(getNextNo()).setName(name)
                        .setParentId(parentId)
                        .setParkCode(parkCode)
                        .setDelFlag(new Integer(0))
                        .setCreateTime(Long.valueOf(DateUtils.getTime()))
                        .setType(type)
                        .setClassify(classify);
                if (this.save(tParkMemberGroup)) {
                    return getSuccessResultJson(true);
                } else {
                    return getFailResultJson(false);
                }
            } else { // 说明同级目录下已存在当前节点
                return getSuccessResultJson(true);
            }
        } else if (GroupType.ONE.type.compareTo(type) == 0) { //新增子卡
            //判断parkCodes是否为空
            if (StringUtils.isBlank(parkCodes)) {
                return getFailResultJson("请选择要绑定的停车场");
            }
            //判断parentId为id的目录是否存在
//                if (itParkMemberGroupService.getById(parentId) == null) {
//                    return getFailResultJson("当前目录不存在");
//                }
            String[] parkCodeArray = parkCodes.split(",|，");
            Stream.of(parkCodeArray).forEach(parkCode -> {
                //判断每个停车场是否已经有初始化的根节点以及访客车，白名单，黑名单
                initTree(parkCode);
                //获取根节点
                QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("park_code", parkCode)
                        .eq("parent_id", 0)
                        .eq("type", GroupType.ZERO.type);
                TParkMemberGroup root = this.getOne(queryWrapper);
                MCardLevelRelations subNode = memberGroupreq.getMCardLevelRelations();
                //去除根节点，只需要除根节点之外的层级结构
                subNode = this.UpwardGetTree(subNode).getChild();
                while (subNode != null && StringUtils.isNotBlank(subNode.getName()) && (subNode.getType().compareTo(GroupType.ZERO.type) == 0 || subNode.getType().compareTo(GroupType.ONE.type) == 0)) {
                    String subCardName = subNode.getName();
                    Integer subCardType = subNode.getType();
                    //判断是否当前节点在当前目录下是否已经存在
                    TParkMemberGroup existInParentNode = this.isExistInParentNode(subCardName, parkCode, root.getId());
                    if (existInParentNode == null) {
                        //将一个child绑定到车场根节点下
                        existInParentNode = new TParkMemberGroup()
                                .setNo(this.getNextNo())
                                .setName(subCardName)
                                .setParentId(root.getId())
                                .setParkCode(parkCode)
                                .setDelFlag(0)
                                .setCreateTime(Long.valueOf(DateUtils.getTime()))
                                .setType(subCardType)
                                .setClassify(classify);
                        //插入子节点
                        //Long subId = this.insertMemberGroup(existInParentNode);
                        this.save(existInParentNode);
                        // log.info("插入成功，子节点的id为" + subId);
                    }
                    //更新根节点及子节点
                    root = existInParentNode;
                    subNode = subNode.getChild();
                }
            });
            return getSuccessResultJson(true);
        } else {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg("无此类型的会员月卡分组")
                    .setData(null);
        }
    }

    @Override
    public ResultJson insertMemberGroup_old(MemberGroupReq memberGroupreq) {
        Integer type = memberGroupreq.getType();
        String name = memberGroupreq.getName();
        String parkCodes = memberGroupreq.getParkCodes();
        Long parentId = memberGroupreq.getParentId();
        if (GroupType.ZERO.type.compareTo(type) == 0) { //新增目录时界面不能绑定停车场，因此parkcode直接传当前停车场的code
            //判断parkCodes是否为空
//                if (StringUtils.isNotBlank(parkCodes)) {
//                    return getFailResultJson("会员分组目录不能绑定停车场");
//                }
            String[] parkCodeArray = parkCodes.split(",|，");
            if (parkCodeArray.length > 1) {
                return getFailResultJson("新增目录只能绑定当前停车场");
            }
            //判断同级目录下当前节点名称是否已经存在
            String parkCode = parkCodeArray[0];
            TParkMemberGroup existInParentNode = this.isExistInParentNode(name, parkCode, parentId);
            if (existInParentNode == null) {
                TParkMemberGroup tParkMemberGroup = new TParkMemberGroup();
                tParkMemberGroup.setNo(this.getNextNo()).setName(name)
                        .setParentId(parentId)
                        .setParkCode(parkCode)
                        .setDelFlag(new Integer(0))
                        .setCreateTime(Long.valueOf(DateUtils.getTime()))
                        .setType(type);
                if (this.save(tParkMemberGroup)) {
                    return getSuccessResultJson(true);
                } else {
                    return getFailResultJson(false);
                }
            } else { // 说明同级目录下已存在当前节点
                return getSuccessResultJson(true);
            }
        } else if (GroupType.ONE.type.compareTo(type) == 0) { //新增子卡
            //判断parkCodes是否为空
            if (StringUtils.isBlank(parkCodes)) {
                return getFailResultJson("请选择要绑定的停车场");
            }
            //判断parentId为id的目录是否存在
//                if (itParkMemberGroupService.getById(parentId) == null) {
//                    return getFailResultJson("当前目录不存在");
//                }

            String[] parkCodeArray = parkCodes.split(",|，");
            List<TParkMemberGroup> parkMemberGroupList = new ArrayList<TParkMemberGroup>();
            Long nextNo = this.getNextNo();
            Stream.of(parkCodeArray).forEach(parkCode -> {
                //判断每个停车场是否已经有初始化的根节点以及访客车，白名单，黑名单
                initTree(parkCode);
                TParkMemberGroup tParkMemberGroup = new TParkMemberGroup()
                        .setNo(nextNo)
                        .setName(name)
                        .setParentId(parentId)
                        .setParkCode(parkCode)
                        .setDelFlag(new Integer(0))
                        .setCreateTime(Long.valueOf(DateUtils.getTime()))
                        .setType(type);
                parkMemberGroupList.add(tParkMemberGroup);
            });
            if (this.saveBatch(parkMemberGroupList)) {
                return getSuccessResultJson(true);
            } else {
                return getFailResultJson(false);
            }
        } else {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg("无此类型的会员月卡分组")
                    .setData(null);
        }
    }

    @Override
    public ResultJson deleteMemberGroupById(Long id, Integer delFlag) {
        //根据id查询月卡分组
        TParkMemberGroup memberGroup = this.getById(id);
        //Long no = memberGroup.getNo();
        if (memberGroup != null) {
            Integer type = memberGroup.getType();
            if (GroupType.ZERO.type.compareTo(type) == 0) {  //如果是目录，递归获取目录及子卡，全部禁用
                //递归获取会员分组月卡信息
                List<TParkMemberGroup> list = new ArrayList<>();
                List<TParkMemberGroup> resultList = new ArrayList<>();
                list.add(memberGroup);
                resultList = getSubCardByRecursion(list, resultList);
                //首先判断当前目录下的子卡是否还存在未到期的用户
                if (delFlag.compareTo(new Integer(1)) == 0) { //禁用需要判断
                    String ids = resultList.parallelStream().map(x -> "" + x.getId())
                            .collect(Collectors.joining(","));
                    boolean existMemberOnGroup = this.isExistMemberOnGroup(ids);
                    if (existMemberOnGroup) {
                        return getFailResultJson("当前目录或者子卡下还有未到期的用户!");
                    }
                }
                if (resultList != null && resultList.size() > 0) {
                    for (TParkMemberGroup group : resultList) {
                        group.setDelFlag(delFlag);
                    }
                    this.updateBatchById(resultList);
                }
                return getSuccessResultJson(true);

            } else if (GroupType.ONE.type.compareTo(type) == 0) { //如果是卡证直接禁用就可以了
                if (delFlag.compareTo(new Integer(1)) == 0) { //禁用操作
                    boolean existMemberOnGroup = this.isExistMemberOnGroup(String.valueOf(id));
                    if (existMemberOnGroup) {
                        return getFailResultJson("当前子卡下还有未到期的用户!");
                    }
                }
                memberGroup.setDelFlag(delFlag);
                boolean b = this.updateById(memberGroup);
                if (b) {
                    return getSuccessResultJson(true);
                } else {
                    return getFailResultJson(false);
                }
            } else {
                return getFailResultJson("无此类型的会员月卡分组");
            }
        } else {
            return getFailResultJson("无此会员月卡分组");
        }
    }


    @Override
    public ResultJson deleteMemberGroupById_NEW(Long id) {
        //根据id查询月卡分组
        TParkMemberGroup memberGroup = this.getById(id);
        //Long no = memberGroup.getNo();
        if (memberGroup != null) {
            Integer type = memberGroup.getType();
            if (GroupType.ZERO.type.compareTo(type) == 0) {  //如果是目录，递归获取目录及子卡，全部禁用
                //递归获取会员分组月卡信息
                List<TParkMemberGroup> list = new ArrayList<>();
                List<TParkMemberGroup> resultList = new ArrayList<>();
                list.add(memberGroup);
                resultList = getSubCardByRecursion(list, resultList);
                //首先判断当前目录下的子卡是否还存在未到期的用户
                // if (delFlag.compareTo(new Integer(1)) == 0) { //禁用需要判断
                String ids = resultList.parallelStream().map(x -> "" + x.getId())
                        .collect(Collectors.joining(","));
                boolean existMemberOnGroup = this.isExistMemberOnGroup(ids);
                if (existMemberOnGroup) {
                    return getFailResultJson("当前目录或者子卡下还有未到期的用户!");
                }
                //  }
                if (resultList != null && resultList.size() > 0) {
//                    for (TParkMemberGroup group : resultList) {
//                        group.setDelFlag(delFlag);
//                    }
//                    this.updateBatchById(resultList);
                    List<Long> idLongs = resultList.parallelStream().map(x -> x.getId())
                            .collect(Collectors.toList());
                    this.removeByIds(idLongs);
                }
                return getSuccessResultJson(true);

            } else if (GroupType.ONE.type.compareTo(type) == 0) { //如果是卡证直接禁用就可以了
                // if (delFlag.compareTo(new Integer(1)) == 0) { //禁用操作
                boolean existMemberOnGroup = this.isExistMemberOnGroup(String.valueOf(id));
                if (existMemberOnGroup) {
                    return getFailResultJson("当前子卡下还有未到期的用户!");
                }
                // }
                // memberGroup.setDelFlag(delFlag);
                boolean b = this.removeById(memberGroup.getId());
                if (b) {
                    return getSuccessResultJson(true);
                } else {
                    return getFailResultJson(false);
                }
            } else {
                return getFailResultJson("无此类型的会员月卡分组");
            }
        } else {
            return getFailResultJson("无此会员月卡分组");
        }
    }

    @Override
    public ResultJson configFullFree(String json) {
        Map map = JSON.parseObject(json, Map.class);
        //is_fullFree 1 开启   0 关闭
        String is_fullFree = map.get("is_fullFree").toString();
        String clear_amt_date ="";

        Long memberGroupId = Long.valueOf(map.get("memberGroupId").toString());//子卡id
        BigDecimal fullFree_amt = BigDecimal.ZERO;

        if ("0".equals(is_fullFree)) {

            QueryWrapper<TParkMemberGroupRelation> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("group_id", memberGroupId);
            List<TParkMemberGroupRelation> list = relationService.list(queryWrapper);
            for (int i = 0; i < list.size(); i++) {
                TParkGroupMemberinfo memberinfo = memberinfoService.getById(list.get(i).getMemberId());
                if (memberinfo != null) {
                    BigDecimal accumulateAmt = memberinfo.getAccumulateAmt() == null ? BigDecimal.ZERO : memberinfo.getAccumulateAmt();
                    if (accumulateAmt.compareTo(BigDecimal.ZERO) != 0) {
                        return getFailResultJson("卡组下已存在用户满足满免额度的情况!");
                    }
                }


            }
        }

        if ("1".equals(is_fullFree)) {
            clear_amt_date = map.get("clear_amt_date").toString();
            TParkMemberGroup byId = this.getById(memberGroupId);
            if (byId.getRegionCode() == null || "".equals(byId.getRegionCode())) {
                return getFailResultJson("卡组请先配置区域!");
            }
            Long feeIndexId = byId.getFeeIndexId() == null ? 0 : byId.getFeeIndexId();

            if (feeIndexId.intValue() == 0) {
                return getFailResultJson("卡组请先配置计费!");
            }

            try {
                fullFree_amt = new BigDecimal(map.get("fullFree_amt").toString());
                if (fullFree_amt.compareTo(BigDecimal.ZERO) == 0) {
                    return getFailResultJson("满免额度不能为0");
                }
            } catch (Exception e) {
                return getFailResultJson("满免额度设置错误");
            }
        }
        boolean updateById = this.updateById(new TParkMemberGroup().setId(memberGroupId).setIsFullFree(Integer.valueOf(is_fullFree)).setFullFreeAmt(fullFree_amt).setClearAmtDate(clear_amt_date));
        if (updateById) {

            TParkMemberGroup byId = this.getById(memberGroupId);

            Long feesroleinfoId = byId.getFeesroleinfoId() == null ? 0 : byId.getFeesroleinfoId();
            if (feesroleinfoId.intValue() != 0) {
                TCarFeesroleinfo tCarFeesroleinfo = itCarFeesroleinfoService.getById(feesroleinfoId);
                byId.setStartTime(tCarFeesroleinfo.getStartTime());
                byId.setEndTime(tCarFeesroleinfo.getEndTime());
            }
            mqService.mqSend(JSON.toJSONString(byId), Constant.MEMBERGROUP_QUEUENAME_PREFIX + byId.getParkCode());
            return getSuccessResultJson("满免额度设置成功");
        } else {
            return getFailResultJson("满免额度设置失败");
        }

    }


    @Override
    public ResultJson selectTree(String parkCode) {
        //根据最上层父级custId和parkName查询停车场的parkCode
//            String parkCode = itParkInfoService.getParkCodeByCustIdAndParkName(custId, parkName);
        if (StringUtils.isBlank(parkCode)) {
            return getFailResultJson("停车场编码不能为空");
        }
        //初始化根节点目录
        QueryWrapper<TParkMemberGroup> tParkMemberGroupWrapper = new QueryWrapper<>();
        tParkMemberGroupWrapper.eq("park_code", parkCode);
        tParkMemberGroupWrapper.eq("parent_id", 0);
        tParkMemberGroupWrapper.eq("type", GroupType.ZERO.type);
        //如果没有根节点则创建一个根节点
        TParkMemberGroup root = null;
        TParkMemberGroupDto resultTree = new TParkMemberGroupDto();
        try {
            root = this.getOne(tParkMemberGroupWrapper, true);
        } catch (Exception e) {
            return getFailResultJson("当前停车场月卡分组根节点只能有一个");
        }
        if (root == null) {  //没有根节点
            root = initTree(parkCode);
            BeanUtils.copyProperties(root, resultTree);
            resultTree = getMemberGroupTree(resultTree, parkCode);
        } else {
            BeanUtils.copyProperties(root, resultTree);
//                TParkMemberGroupDto tempTree = new TParkMemberGroupDto();
            resultTree = getMemberGroupTree(resultTree, parkCode);
        }
        return RESULT_JSON.setCode(ResultCode.SUCCESS)
                .setMsg(ResultCode.SUCCESS_MSG)
                .setData(resultTree);
    }

    @Override
    public ResultJson selectTreeByKey(String parkCode, TParkMemberGroupDto groupDto, String key) {
        if (StringUtils.isBlank(parkCode)) {
            return getFailResultJson("停车场编码不能为空");
        }
        //获取子节点
        List<TParkMemberGroupDto> childs = groupDto.getChilds();
        //如果有子节点
        if (childs != null) {
            Iterator<TParkMemberGroupDto> iterator = childs.iterator();
            while (iterator.hasNext()) {
                TParkMemberGroupDto memberGroupDto = iterator.next();
                if (memberGroupDto.getType().compareTo(GroupType.ZERO.type) == 0) { //目录
                    selectTreeByKey(parkCode, memberGroupDto, key);
                    if (memberGroupDto.getChilds() == null || memberGroupDto.getChilds().size() < 1) {
                        iterator.remove();
                    }
                } else if (memberGroupDto.getType().compareTo(GroupType.ONE.type) == 0) {//卡证
                    if (!memberGroupDto.getName().contains(key)) { //如果卡证名称不包含key，则直接移除掉
                        iterator.remove();
                    }
                }
                groupDto.setChilds(childs);
            }
        }
        return getSuccessResultJson(groupDto);
    }

    @Override
    public ResultJson updateMemberGroup(MemberGroupReq memberGroupreq) {
        Long no = memberGroupreq.getNo();
        Integer type = memberGroupreq.getType();
        String name = memberGroupreq.getName();
        Long parentId = memberGroupreq.getParentId();
        String parkCodes = memberGroupreq.getParkCodes();
        if (no != null) {
            if (GroupType.ZERO.type.compareTo(type) == 0) { //修改目录
//                    if (StringUtils.isNotBlank(parkCodes)) {
//                        return getFailResultJson("会员分组目录不能绑定停车场");
//                    }
                //判断parentId是否为0
//                    if (new Long(0).compareTo(parentId) != 0) {
//                        return getFailResultJson("会员分组目录parentId必须为0");
//                    }
                //相同no的目录是唯一的
                List<TParkMemberGroup> parkMemberGroups = this.selectMemberGroupByNoAndType(no, type);
                if (parkMemberGroups != null && parkMemberGroups.size() > 0) {
                    TParkMemberGroup tParkMemberGroup = parkMemberGroups.get(0);
                    //目录只能修改一个目录名称
                    tParkMemberGroup.setNo(no).setName(name)
                            .setUpdateTime(Long.valueOf(DateUtils.getTime()));

                    if (this.updateById(tParkMemberGroup)) {
                        return getSuccessResultJson(true);
                    } else {
                        return getFailResultJson(false);
                    }
                } else {
                    return getFailResultJson("当前目录不存在");
                }
            } else if (GroupType.ONE.type.compareTo(type) == 0) { //修改卡证
                //判断parkCodes是否为空
                if (StringUtils.isBlank(parkCodes)) {
                    return getFailResultJson("请选择要绑定的停车场");
                }
                //判断parentId为id的目录是否存在
                if (this.getById(parentId) == null) {
                    return getFailResultJson("当前目录不存在");
                }
                //根据no和type查询月卡分组，如果是子卡可能会有多个相同的no，但是parkcode不同
                List<TParkMemberGroup> parkMemberGroupList = this.selectMemberGroupByNoAndType(no, type);
                String[] parkCodeArray = parkCodes.split(",|，");
                List<String> readyExistsParkCodeList = parkMemberGroupList.parallelStream()
                        .filter(x -> StringUtils.isNotBlank(x.getParkCode()))
                        .map(x -> {
                            return x.getParkCode();
                        }).collect(Collectors.toList());
                List<String> willUpdateParkCodeList = Arrays.asList(parkCodeArray);
                willUpdateParkCodeList = new ArrayList<>(willUpdateParkCodeList);
                //子卡可以修改name 和 parkCode

                List<String> a = new ArrayList<>(readyExistsParkCodeList);
                List<String> b = new ArrayList<>(willUpdateParkCodeList);
                //新增的停车场
                b.removeAll(a);
                System.out.println(b);
                if (b != null && b.size() > 0) {
                    List<TParkMemberGroup> insertList = new ArrayList<TParkMemberGroup>();
                    b.forEach(parkCode -> {
                        TParkMemberGroup tParkMemberGroup = new TParkMemberGroup()
                                .setNo(no)
                                .setName(name)
                                .setParentId(parentId)
                                .setParkCode(parkCode)
                                .setDelFlag(new Integer(0))
                                .setCreateTime(Long.valueOf(DateUtils.getTime()))
                                .setType(type);
                        insertList.add(tParkMemberGroup);
                    });
                    boolean insertResult = this.saveBatch(insertList);
                    if (insertResult) {
                        log.info("新增了" + insertList.size() + "条编号no为" + no + "的记录");
                    }
                }
                List<String> c = new ArrayList<>(readyExistsParkCodeList);
                List<String> d = new ArrayList<>(willUpdateParkCodeList);
                //删除的停车场
                c.removeAll(d);
                System.out.println(c);
                if (c != null && c.size() > 0) {
                    String parkCodesIn = c.parallelStream().filter(x -> StringUtils.isNotBlank(x)).collect(Collectors.joining(","));
                    Map<String, Object> paramMap = new HashMap<>();
                    paramMap.put("no", no);
                    paramMap.put("type", type);
                    paramMap.put("parkCodes", parkCodesIn);
                    int deleteResult = this.deleteByParamMap(paramMap);
                    if (deleteResult > 0) {
                        log.info("删除了" + deleteResult + "条编号no为" + no + "的记录");
                    }
                }

                //不做新增或删除的停车场，仅仅修改月卡name
                List<String> e = new ArrayList<>(readyExistsParkCodeList);
                List<String> f = new ArrayList<>(willUpdateParkCodeList);
                e.retainAll(f);
                if (e != null && e.size() > 0) {
                    List<TParkMemberGroup> invariantMemberGroup = parkMemberGroupList.parallelStream()
                            .filter(x -> f.contains(x.getParkCode()))
                            .map(x -> {
                                x.setName(name);
                                x.setUpdateTime(Long.valueOf(DateUtils.getTime()));
                                return x;
                            }).collect(Collectors.toList());
                    boolean updateResult = this.updateBatchById(invariantMemberGroup);
                    if (updateResult) {
                        log.info("更新了" + invariantMemberGroup.size() + "条编号no为" + no + "记录的名称");
                    }
                }
                return getSuccessResultJson(true);
            } else {
                return RESULT_JSON.setCode(ResultCode.FAIL)
                        .setMsg("无此类型的会员月卡分组")
                        .setData(null);
            }
        } else {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg("会员月卡分组编号不能为空")
                    .setData(null);
        }
    }

    @Override
    public ResultJson updateMemberGroup2(MemberGroupReq memberGroupreq) {
        Integer id = memberGroupreq.getId();
        Long no = memberGroupreq.getNo();
        Integer type = memberGroupreq.getType();
        String name = memberGroupreq.getName();
        Long parentId = memberGroupreq.getParentId();
        String parkCodes = memberGroupreq.getParkCodes();
        if (id != null) {
            if (GroupType.ZERO.type.compareTo(type) == 0) { //修改目录
//                    if (StringUtils.isNotBlank(parkCodes)) {
//                        return getFailResultJson("会员分组目录不能绑定停车场");
//                    }
                //判断parentId是否为0
//                    if (new Long(0).compareTo(parentId) != 0) {
//                        return getFailResultJson("会员分组目录parentId必须为0");
//                    }
                //相同no的目录是唯一的
                TParkMemberGroup tParkMemberGroup = this.getById(id);
                if (tParkMemberGroup != null) {
                    //  TParkMemberGroup tParkMemberGroup = parkMemberGroups.get(0);
                    //目录只能修改一个目录名称
                    tParkMemberGroup.setName(name)
                            .setUpdateTime(Long.valueOf(DateUtils.getTime()));
                    if (this.updateById(tParkMemberGroup)) {
                        return getSuccessResultJson(true);
                    } else {
                        return getFailResultJson(false);
                    }
                } else {
                    return getFailResultJson("当前目录不存在");
                }
            } else if (GroupType.ONE.type.compareTo(type) == 0) { //修改卡证
                //判断parkCodes是否为空
                if (StringUtils.isBlank(parkCodes)) {
                    return getFailResultJson("请选择要绑定的停车场");
                }
                //判断parentId为id的目录是否存在
                if (this.getById(parentId) == null) {
                    return getFailResultJson("当前目录不存在");
                }

                String[] beforeParkCodeArray = parkCodes.split(",|，"); // 之前的parkCodes
                String[] afterParkCodeArray = parkCodes.split("，|,");  //更新之后的parkCodes
                //todo 假使前端传入当前停车场修改之前的parkCodes数组，以及修改之后
                //todo 绑定的停车场数组
                //分别转换成两个list
                List<String> readyExistsParkCodeList = new ArrayList<>(Arrays.asList(beforeParkCodeArray));
                List<String> willUpdateParkCodeList = new ArrayList<>(Arrays.asList(afterParkCodeArray));

                List<String> a = new ArrayList<>(readyExistsParkCodeList);
                List<String> b = new ArrayList<>(willUpdateParkCodeList);
                //新增的停车场
                b.removeAll(a);
                System.out.println(b);
                if (b != null && b.size() > 0) {
                    //前端传入层级关系，进行级联创建
                }
                List<String> c = new ArrayList<>(readyExistsParkCodeList);
                List<String> d = new ArrayList<>(willUpdateParkCodeList);
                //删除的停车场
                c.removeAll(d);
                System.out.println(c);
                if (c != null && c.size() > 0) {
                    //需要删除层级关系一致的当前子卡
                }

                //不做新增或删除的停车场，仅仅修改月卡name
                List<String> e = new ArrayList<>(readyExistsParkCodeList);
                List<String> f = new ArrayList<>(willUpdateParkCodeList);
                e.retainAll(f);
                if (e != null && e.size() > 0) {
                    List<String> invariantMemberGroup = willUpdateParkCodeList.parallelStream()
                            .filter(x -> f.contains(x))
                            .collect(Collectors.toList());
                    //查询多parkcode的当前层级的子卡记录进行更新
                    //todo

//                        boolean updateResult = itParkMemberGroupService.updateBatchById(invariantMemberGroup);
//                        if (updateResult) {
//                            log.info("更新了" + invariantMemberGroup.size() + "条编号no为" + no + "记录的名称");
//                        }
                }
                return getSuccessResultJson(true);


            } else {
                return RESULT_JSON.setCode(ResultCode.FAIL)
                        .setMsg("无此类型的会员月卡分组")
                        .setData(null);
            }
        } else {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg("会员月卡分组编号不能为空")
                    .setData(null);
        }
    }


    /**
     * 初始化树形结构
     *
     * @param parkCode
     * @return
     */
    public TParkMemberGroup initTree(String parkCode) {
        TParkMemberGroup root = null;
        try {
            //初始化根节点
            QueryWrapper<TParkMemberGroup> tParkMemberGroupWrapper = new QueryWrapper<>();
            tParkMemberGroupWrapper.eq("park_code", parkCode);
            tParkMemberGroupWrapper.eq("parent_id", 0);
            tParkMemberGroupWrapper.eq("type", GroupType.ZERO.type);
            //如果没有根节点则创建一个根节点

            TParkMemberGroupDto resultTree = new TParkMemberGroupDto();
            try {
                root = this.getOne(tParkMemberGroupWrapper, true);
            } catch (Exception e) {
                log.error("当前停车场月卡分组根节点只能有一个", e);
            }
            if (root == null) {  //没有根节点
                QueryWrapper<TParkInfo> tParkInfoQueryWrapper = new QueryWrapper<>();
                tParkInfoQueryWrapper.select("name")
                        .eq("park_code", parkCode);
                TParkInfo parkInfo = itParkInfoService.getOne(tParkInfoQueryWrapper);
                if (parkInfo == null) {
                    log.error("当前停车场不存在");
                }
                String name = parkInfo.getName();
                root = new TParkMemberGroup()
                        .setNo(this.getNextNo())
                        .setName(name)
                        .setParentId(0L)
                        .setParkCode(parkCode)
                        .setDelFlag(0)
                        .setCreateTime(Long.valueOf(DateUtils.getTime()))
                        .setType(GroupType.ZERO.type)
                        .setClassify(Constant.ROOT_CLASSIFY);
                this.save(root);
            }
            //再次查询为了获取根节点的id
            root = this.getOne(tParkMemberGroupWrapper, true);
            Long rootId = root.getId();
            //创建临停车节点
            createInitSubNode(parkCode, Constant.PARKING_CAR, rootId, Constant.PARKING_CAR_CLASSIFY);
            //创建访客车节点
            createInitSubNode(parkCode, Constant.VISITOR_CAR, rootId, Constant.VISITOR_CAR_CLASSIFY);
            //创建白名单节点
            createInitSubNode(parkCode, Constant.WHITE_LIST, rootId, Constant.WHITE_LIST_CLASSIFY);
            //创建黑名单节点
            createInitSubNode(parkCode, Constant.BLACK_LIST, rootId, Constant.BLACK_LIST_CLASSIFY);

        } catch (Exception e) {
            log.error("初始化树形月卡分组异常", e);
        }
        return root;
    }

    /**
     * 创建根节点下的一级目录，临停车目录，访客车目录，白名单目录，黑名单目录
     */
    public void createInitSubNode(String parkCode, String name, Long rootId, Integer classify) {
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        queryWrapper.eq("park_code", parkCode);
        queryWrapper.eq("type", GroupType.ZERO.type); //目录
        queryWrapper.eq("parent_id", rootId);
        TParkMemberGroup subMemberGroup = this.getOne(queryWrapper, true);
        if (subMemberGroup == null) {
            //创建临停车证
            subMemberGroup = new TParkMemberGroup()
                    .setNo(this.getNextNo())
                    .setName(name)
                    .setParentId(rootId)
                    .setParkCode(parkCode)
                    .setDelFlag(0)
                    .setCreateTime(Long.valueOf(DateUtils.getTime()))
                    .setType(GroupType.ZERO.type)
                    .setClassify(classify);
            boolean save = this.save(subMemberGroup);
            if (save) {  //如果父节点创建成功，再创建子节点
                Long parentId = this.getOne(queryWrapper, true).getId();
                //根据临停车目录，访客车目录，白名单目录，黑名单目录创建各个子卡
                String subCardName = "";
                if (Constant.PARKING_CAR.equals(name)) {
                    subCardName = Constant.PARKING_CAR_CARD;
                } else if (Constant.WHITE_LIST.equals(name)) {
                    subCardName = Constant.WHITE_LIST_CARD;
                } else if (Constant.BLACK_LIST.equals(name)) {
                    subCardName = Constant.BLACK_LIST_CARD;
                } else if (Constant.VISITOR_CAR.equals(name)) {
                    subCardName = Constant.VISITOR_CAR_CARD;
                }
                //查询是否在父级节点下已存在
                TParkMemberGroup subCard = this.isExistInParentNode(subCardName, parkCode, parentId);
                if (subCard == null) {
                    //创建各个子卡
                    subCard = new TParkMemberGroup()
                            .setNo(this.getNextNo())
                            .setName(subCardName)
                            .setParentId(parentId)
                            .setParkCode(parkCode)
                            .setDelFlag(0)
                            .setCreateTime(Long.valueOf(DateUtils.getTime()))
                            .setType(GroupType.ONE.type)
                            .setClassify(classify);
                    this.save(subCard);
                }
            }
        }
    }


    /**
     * 删除接口递归获取子节点
     *
     * @param parkMemberGroupList
     * @param resultList
     * @return
     */
    private List<TParkMemberGroup> getSubCardByRecursion(List<TParkMemberGroup> parkMemberGroupList, List<TParkMemberGroup> resultList) {
        for (TParkMemberGroup group : parkMemberGroupList) {
            if (GroupType.ZERO.type.compareTo(group.getType()) == 0) {
                resultList.add(group);
                Long id = group.getId();
                QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("parent_id", id);
                List<TParkMemberGroup> list = this.list(queryWrapper);
                getSubCardByRecursion(list, resultList);
            } else {
                resultList.add(group);
            }
        }
        return resultList;
    }


    /**
     * 查询接口组装会员月卡分组树形结构
     *
     * @param tParkMemberGroupDto
     * @return
     */
    private TParkMemberGroupDto getMemberGroupTree(TParkMemberGroupDto tParkMemberGroupDto, String parkCode) {
        //if (GroupType.ZERO.type.compareTo(tParkMemberGroupDto.getType()) == 0) { //是目录
        Long id = tParkMemberGroupDto.getId();
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        //  queryWrapper.eq("del_flag", 0); //只需要显示没有被禁用的目录和卡组
        List<TParkMemberGroupDto> list = this.list(queryWrapper).parallelStream()
                .map(x -> {
                    TParkMemberGroupDto newDto = new TParkMemberGroupDto();
                    BeanUtils.copyProperties(x, newDto);
                    //套餐金额
                    QueryWrapper<TCarFeesroleinfo> wrapper = new QueryWrapper<>();
                    if (x.getFeesroleinfoId() != null) {
                        wrapper.eq("id", x.getFeesroleinfoId())
                                .select("month_value", "role_name", "card_type");
                        TCarFeesroleinfo feesroleinfo = itCarFeesroleinfoService.getOne(wrapper);
                        if (feesroleinfo != null) {
                            newDto.setMonthValue(feesroleinfo.getMonthValue());
                            newDto.setRoleName(feesroleinfo.getRoleName());
                            newDto.setCardType(feesroleinfo.getCardType());
                        }
                    }
                    return newDto;
                }).collect(Collectors.toList());
        tParkMemberGroupDto.getChilds().addAll(list.parallelStream().filter(x -> StringUtils.isBlank(x.getParkCode()) || parkCode.equals(x.getParkCode())).collect(Collectors.toList()));
        for (TParkMemberGroupDto group : list) {
            getMemberGroupTree(group, parkCode);
        }
        // }
        return tParkMemberGroupDto;
    }

    @Override
    public Long getNextNo() {
        Long maxNo = tParkMemberGroupMapper.selectMaxNo();
        return maxNo == null ? 0 : ++maxNo;
    }


    @Override
    public List<TParkMemberGroup> selectMemberGroupByNoAndType(Long no, Integer type) {
        return tParkMemberGroupMapper.selectMemberGroupByNoAndType(no, type);
    }

    @Override
    public int deleteByParamMap(Map<String, Object> paramMap) {
        return tParkMemberGroupMapper.deleteByParamMap(paramMap);
    }

    @Override
    public TParkMemberGroup isExistInParentNode(String memberGroupName, String parkCode, Long parentId) {
        return tParkMemberGroupMapper.isExistInParentNoder(memberGroupName, parkCode, parentId);
    }

    @Override
    public Long insertMemberGroup(TParkMemberGroup tParkMemberGroup) {
        return tParkMemberGroupMapper.insertMemberGroup(tParkMemberGroup);
    }

    @Override
    public boolean isExistMemberOnGroup(String ids) {
        //遍历ids
        int count = 0;
        if (StringUtils.isNotBlank(ids)) {
            String[] idArray = ids.split(",|，");
            //根据ids查询出要禁用的目录和卡证
            QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<TParkMemberGroup>();
            queryWrapper.in("id", idArray);
            //过滤调目录，保留卡证
            List<TParkMemberGroup> collect = this.list(queryWrapper).parallelStream()
                    .filter(x -> x.getType().compareTo(GroupType.ONE.type) == 0)
                    .collect(Collectors.toList());
            //获取当前日期
            Integer now = Integer.valueOf(DateUtils.getTimeYMD());
            for (TParkMemberGroup memberGroup : collect) {
                Integer classify = memberGroup.getClassify();
                Long id = memberGroup.getId();
                //临停车无需判断是否还存在未过期的用户
                //根据卡证类别分别查询不同的表，获取未过期的用户数量
                if (classify.compareTo(Constant.VISITOR_CAR_CLASSIFY) == 0) { //访客车
                    count += tParkMemberGroupMapper.isExistVisitorMemberOnGroup(id, now);
                } else if (classify.compareTo(Constant.WHITE_LIST_CLASSIFY) == 0) { //白名单
                    count += tParkMemberGroupMapper.isExistWhiteMemberOnGroup(id, now);
                } else if (classify.compareTo(Constant.BLACK_LIST_CLASSIFY) == 0) { //黑名单
                    count += tParkMemberGroupMapper.isExistBlackMemberOnGroup(id, now);
                } else if (classify.compareTo(Constant.CUSTOM_CAR_CLASSIFY) == 0) { //自定义卡组
                    count += tParkMemberGroupMapper.isExistCustomMemberOnGroup(id, now);
                }
            }
        }
        return count > 0;
    }

    @Override
    public List<String> selectByParentId(List<String> stringList, Long id) {
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        queryWrapper.eq("del_flag", 0); //只需要显示没有被禁用的目录和卡组
        List<TParkMemberGroupDto> list = this.list(queryWrapper).parallelStream()
                .map(x -> {
                    TParkMemberGroupDto newDto = new TParkMemberGroupDto();
                    BeanUtils.copyProperties(x, newDto);
                    return newDto;
                }).collect(Collectors.toList());

        for (TParkMemberGroupDto group : list) {
            selectByParentId(stringList, group.getId());
        }

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getType().compareTo(new Integer(1)) == 0) {
                stringList.add(list.get(i).getId().toString());
            }
        }
        List<Long> collect = stringList.stream()
                .map(s -> Long.parseLong(s))
                .collect(Collectors.toList());
        Collections.sort(collect);
        List<String> collect1 = collect.stream()
                .map(s -> String.valueOf(s))
                .collect(Collectors.toList());
        return collect1;
    }


    /**
     * 向上循环获取卡组树形结构
     *
     * @param relations
     * @return
     */
    @Override
    public MCardLevelRelations UpwardGetTree(MCardLevelRelations relations) {
        MCardLevelRelations tree = relations;
        //循环次数限制为20次，树形结构深度，防止无限循环
        int count = 20;
        while (tree.getParentId().compareTo(new Long(0)) != 0 && count >= 0) {
            //查询 id为  当前的父节点的 parentId的 记录
            Long parentId = tree.getParentId();
            QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<TParkMemberGroup>();
            queryWrapper.eq("id", parentId);
            TParkMemberGroup one = this.getOne(queryWrapper);

            MCardLevelRelations groupPaternityDto = new MCardLevelRelations()
                    .setId(one.getId())
                    .setName(one.getName())
                    .setParentId(one.getParentId())
                    .setType(one.getType())
                    .setChild(tree);
            //将当前节点设置为查询到的父节点的子节点
            tree = groupPaternityDto;
            //循环次数减1
            count--;
            if (count < 0) {
                break;
            }
        }
        return tree;
    }


    /**
     * 会员分组类型枚举
     */
    enum GroupType {
        ZERO(new Integer(0), "目录"), ONE(new Integer(1), "卡证");
        private Integer type;
        private String name;

        GroupType(Integer type, String name) {
            this.type = type;
            this.name = name;
        }

        public Integer getType() {
            return type;
        }

        public String getName() {
            return name;
        }
    }


    /**
     * 获取失败返回消息体
     *
     * @param data
     * @return
     */
    private ResultJson getFailResultJson(Object data) {
        return RESULT_JSON.setCode(ResultCode.FAIL)
                .setMsg(data.toString()).setData(null);
    }

    /**
     * 获取成功返回消息体
     *
     * @param data
     * @return
     */
    private ResultJson getSuccessResultJson(Object data) {
        return RESULT_JSON.setCode(ResultCode.SUCCESS)
                .setMsg(ResultCode.SUCCESS_MSG).setData(data);
    }

    @Override
    public ResultJson selectOther(String json) {
        Map map = JSON.parseObject(json, Map.class);
        String parkCode = map.get("parkCode").toString();
        if (StringUtils.isBlank(parkCode)) {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg(Constant.MSG_PARKCODE_NULL).setData(null);
        }
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", parkCode);
        queryWrapper.eq("del_flag", 0);
        queryWrapper.eq("type", 1);
        queryWrapper.gt("classify", 4);
        List<TParkMemberGroup> list = this.list(queryWrapper);
        return RESULT_JSON.setCode(ResultCode.SUCCESS)
                .setMsg(ResultCode.SUCCESS_MSG).setData(list);
    }

    @Override
    public ResultJson selectAll(String json) {
        Map map = JSON.parseObject(json, Map.class);
        String parkCode = map.get("parkCode").toString();
        if (StringUtils.isBlank(parkCode)) {
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg(Constant.MSG_PARKCODE_NULL).setData(null);
        }
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", parkCode);
        queryWrapper.eq("del_flag", 0);
        queryWrapper.eq("type", 0);
        queryWrapper.gt("classify", 1);
        queryWrapper.orderByAsc("classify");
        queryWrapper.orderByAsc("create_time");
        List<TParkMemberGroup> list = this.list(queryWrapper);
        return RESULT_JSON.setCode(ResultCode.SUCCESS)
                .setMsg(ResultCode.SUCCESS_MSG).setData(list);
    }

    @Override
    public ResultJson selectByParent(String json) {
        Map map = JSON.parseObject(json, Map.class);
        String parentId = map.get("parentId").toString();
        List<String> strings = this.selectByParentId(new ArrayList<>(), Long.valueOf(parentId));
        List<Map<String, Object>> list = new ArrayList<>();
        if (strings.size() > 0) {
            list = baseMapper.selectChildInfo(String.join(",", strings));
        }

        return RESULT_JSON.setCode(ResultCode.SUCCESS)
                .setMsg(ResultCode.SUCCESS_MSG).setData(list);
    }

    @Override
    public List<String> getAllWhiteId() {
        return baseMapper.getAllWhiteId();
    }


    /**
     * 根据父卡组id查询所有的子卡证集合
     */
    @Override
    public List<Long> queryGroupIdsByParentId(List<Long> list, Long parentId, String parkCode) {
        QueryWrapper<TParkMemberGroup> qw = new QueryWrapper<>();
        qw.eq("parent_id", parentId);
        qw.eq("park_code", parkCode);
        qw.eq("classify", 5);
        qw.eq("del_flag", 0);
        List<TParkMemberGroup> resp = tParkMemberGroupMapper.selectList(qw);
        boolean flag = true;
        for (TParkMemberGroup tParkMemberGroup : resp) {
            if (tParkMemberGroup.getType() == 0) {  //卡组
                List<Long> strings = this.queryGroupIdsByParentId(list, tParkMemberGroup.getId(), parkCode);
                flag = false;
            } else {
                list.add(tParkMemberGroup.getId());
            }
            /*if (flag) {
                break;
            }*/
        }
        return list;
    }

    @Override
    public String getRegionCodeByFeeIndexId(Long feeIndexId) {
        List<String> list = tParkMemberGroupMapper.getRegionCodesByFeeIndexId(feeIndexId);
        if (!CollectionUtils.isEmpty(list)) {
            String str = list.parallelStream().collect(Collectors.joining(","));
            //去重
            String regionCodes = Arrays.stream(str.split(",|，")).distinct().sorted().collect(Collectors.joining(","));
            return StringUtils.isNotBlank(regionCodes) ? regionCodes : null;
        }
        return null;
    }

    @Override
    public ResultJson syncToFlyos(String json) {
        try {
            Map map = JSON.parseObject(json, Map.class);
            String parkCode = map.get("parkCode").toString();
            QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("park_code", parkCode)
                    .eq("type", 1).isNotNull("fee_index_id");
            List<TParkMemberGroup> tParkMemberGroups = tParkMemberGroupMapper.selectList(queryWrapper)
                    .parallelStream()
                    .map(x -> {
                        //获取绑定了套餐策略的开始时段和结束时段
                        TCarFeesroleinfo carFeesroleinfo = itCarFeesroleinfoService.getById(x.getFeesroleinfoId());
                        if (carFeesroleinfo != null) {
                            x.setStartTime(carFeesroleinfo.getStartTime());
                            x.setEndTime(carFeesroleinfo.getEndTime());
                        }
                        return x;
                    }).collect(Collectors.toList());


            return RESULT_JSON.setCode(ResultCode.SUCCESS)
                    .setMsg(ResultCode.SUCCESS_MSG)
                    .setData(tParkMemberGroups);
        } catch (Exception e) {
            log.error("error", e);
            return RESULT_JSON.setCode(ResultCode.FAIL)
                    .setMsg(ResultCode.FAIL_MSG)
                    .setData(null);
        }
    }

    @Override
    public ResultJson updateCardGroupTotalAmt(Map<String, String> param) {
        try {
            Long groupId = Long.valueOf(param.get("groupId"));
            BigDecimal totalFullFreeAmt = new BigDecimal(param.get("totalFullFreeAmt"));
            TParkMemberGroup tParkMemberGroup = new TParkMemberGroup();
            tParkMemberGroup.setId(groupId);
            tParkMemberGroup.setTotalFullFreeAmt(totalFullFreeAmt);
            boolean res = this.updateById(tParkMemberGroup);
            if (res) {
                return new ResultJson().setCode(ResultCode.SUCCESS)
                        .setMsg(ResultCode.SUCCESS_MSG).setData(true);
            } else {
                return new ResultJson().setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(false);
            }
        } catch (Exception e) {
            log.error("error", e);
            return new ResultJson().setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(false);
        }
    }
}
